package com.hksj.cbm.service;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hksj.cbm.dto.SpaceDeviceBindDTO;
import com.hksj.cbm.dto.SpecialitySpaceBindDTO;
import com.hksj.cbm.entity.ScreenDeviceSpaceSpeciality;
import com.hksj.cbm.entity.SpaceModel;
import com.hksj.cbm.mapper.ScreenDeviceSpaceSpecialityMapper;
import com.hksj.cbm.vo.ScreenDeviceSpaceSpecialityVO;
import com.hksj.cbm.vo.SpaceModelVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zengke
 * @version 1.0
 * @see ScreenDeviceSpaceSpecialityService
 * @since 2024/7/18 17:09
 */

//大屏设备空间专业关联业务
@Service
public class ScreenDeviceSpaceSpecialityService extends ServiceImpl<ScreenDeviceSpaceSpecialityMapper, ScreenDeviceSpaceSpeciality> {

    @Autowired
    private SpaceModelService spaceModelService;

    @Autowired
    private SpecialityModelService specialityModelService;

    /**
     * 查询专业模型下的空间模型绑定关系
     */
    public List<ScreenDeviceSpaceSpecialityVO> queryBindSpaceModelList(Long specialityModelId){
        return baseMapper.queryBindSpaceModelList(specialityModelId);
    }

    /**
     * 绑定专业模型和空间模型的关系
     */
    @Transactional
    public String bindSpaceModel(SpecialitySpaceBindDTO spaceSpecialityBindDTO){

        //获取空间模型集合
        List<Long> spaceModelIdList = spaceSpecialityBindDTO.getSpaceModelIdList();

        //获取专业id
        Long specialityModelId = spaceSpecialityBindDTO.getSpecialityModelId();

        //判断空间模型是否为空
//        Assert.notEmpty(spaceModelIdList,"选中的空间模型不为空");

        //存储将要新增的专业空间关系list
        List<ScreenDeviceSpaceSpeciality> toAddRelation = new ArrayList<>();

        //先删除专业模型和空间模型的绑定关系
        this.lambdaUpdate()
                .eq(ScreenDeviceSpaceSpeciality::getSpecialityModelId,specialityModelId)
                .remove();

        //再新增专业模型下的空间模型
        //若空间模型集合不为空才进行新增
        if (!ObjectUtils.isEmpty(spaceModelIdList)){
            for (Long spaceModelId : spaceModelIdList) {

                //创建专业空间关系对象
                ScreenDeviceSpaceSpeciality screenDeviceSpaceSpeciality = new ScreenDeviceSpaceSpeciality();
                screenDeviceSpaceSpeciality.setSpaceModelId(spaceModelId);
                screenDeviceSpaceSpeciality.setSpecialityModelId(specialityModelId);

                //添加到将要存储的list中
                toAddRelation.add(screenDeviceSpaceSpeciality);
            }

            //批量新增
            super.saveBatch(toAddRelation);
        }

        return "绑定成功";
    }

    /**
     * 查询空间模型下的设备模型绑定关系
     */
    public List<ScreenDeviceSpaceSpecialityVO> queryBindDeviceModelList(Long specialityModelId,Long spaceModelId){

        //查询当前空间模型下的子节点集合
        List<SpaceModelVO> spaceModelList = spaceModelService.querySpaceModelChildren(spaceModelId);

        //获取子节点对应的id集合
        List<Long> childrenIdList = spaceModelList.stream().map(SpaceModelVO::getId).collect(Collectors.toList());

        //子节点为空返回空的集合
        if (CollectionUtil.isEmpty(spaceModelList)){
            return CollectionUtil.newArrayList();
        }

        //子节点不为空,查询子节点对应的那些绑定的设备集合
        List<ScreenDeviceSpaceSpecialityVO> screenDeviceSpaceSpecialityList = baseMapper.queryBindDeviceModelList(specialityModelId,childrenIdList);

        //返回已绑定的设备集合
        return screenDeviceSpaceSpecialityList;
    }


    /**
     * 绑定空间模型和设备模型的关系
     */
    @Transactional
    public String bindDeviceModel(SpaceDeviceBindDTO spaceDeviceBindDTO){

        //获取设备模型集合
        List<Long> deviceModelIdList = spaceDeviceBindDTO.getDeviceModelIdList();

        //获取空间模型id
        Long spaceModelId = spaceDeviceBindDTO.getSpaceModelId();

        //获取专业模型id
        Long specialityModelId = spaceDeviceBindDTO.getSpecialityModelId();

        //通过专业模型id和空间模型id查询记录是否存在,若不存在则说明没有专业模型绑定空间模型 不能让其绑定设备
        List<ScreenDeviceSpaceSpeciality> specialitySpaceBindList = lambdaQuery()
                .eq(ScreenDeviceSpaceSpeciality::getSpecialityModelId, specialityModelId)
                .eq(ScreenDeviceSpaceSpeciality::getSpaceModelId, spaceModelId).list();

        Assert.notEmpty(specialitySpaceBindList,"请先选中并添加空间模型后再绑定设备");


        //先删除专业模型和空间模型关系
        lambdaUpdate().eq(ScreenDeviceSpaceSpeciality::getSpecialityModelId, specialityModelId)
                .eq(ScreenDeviceSpaceSpeciality::getSpaceModelId, spaceModelId)
                .remove();

        //再添加新的关联关系
        List<ScreenDeviceSpaceSpeciality> toAddRelation = new ArrayList<>();

        //若设备模型id集合不为空
        if (!ObjectUtils.isEmpty(deviceModelIdList)){
            for (Long deviceModelId : deviceModelIdList) {
                ScreenDeviceSpaceSpeciality screenDeviceSpaceSpeciality = new ScreenDeviceSpaceSpeciality();
                screenDeviceSpaceSpeciality.setSpecialityModelId(specialityModelId);
                screenDeviceSpaceSpeciality.setSpaceModelId(spaceModelId);
                screenDeviceSpaceSpeciality.setDeviceId(deviceModelId);

                toAddRelation.add(screenDeviceSpaceSpeciality);
            }

            //批量新增
            super.saveBatch(toAddRelation);
        }

        return "绑定成功";
    }

    /**
     * 查询大屏空间模型树
     * @param specialityCode 专业代码
     * @return 模型树
     */
    public List<SpaceModel> queryScreenSpaceModelTree(String specialityCode) {

        //查询模型树绑定的空间模型节点对应的路径集合
        List<String> spaceModelPathList = baseMapper.queryBindSpaceModelPathList(specialityCode);

        //模型的路径为空则返回空的树
        if (ObjectUtils.isEmpty(spaceModelPathList)){
            return null;
        }

        //绑定的空间模型的父节点集合
        Set<String> parentNodeIdSet = new HashSet<>();

        //遍历空间模型节点对应的路径集合,将路径按照","拆分并设置到parentNodeIdSet中 使用set集合去重
        for (String spaceModePath : spaceModelPathList) {
            if (!ObjectUtils.isEmpty(spaceModePath)) {
                parentNodeIdSet.addAll(CollectionUtil.set(false, spaceModePath.split(",")));
            }
        }

        //将set集合转换为list集合
        List<String> parentNodeIdList = CollectionUtil.list(true, parentNodeIdSet);

        //根据id集合查询空间模型
        List<SpaceModel> spaceModelList = spaceModelService.lambdaQuery().in(SpaceModel::getId, parentNodeIdList).orderByAsc(SpaceModel::getSeq).list();

        //调用生成树的方法生成空间模型树

        return SpaceModelService.getChildren(-1L, spaceModelList);

    }
}
